package com.lumlord.service.controlled.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lumlord.mapper.controlled.ControlledInfoMapper;
import com.lumlord.mapper.controlled.ControlledProgramMaterialMapper;
import com.lumlord.mapper.controlled.OperatingUnitInfoMapper;
import com.lumlord.mapper.controlled.ProjectAreaForControlledMapper;
import com.lumlord.mapper.union.BaseOperatingUnitProjectMapper;
import com.lumlord.mapper.union.PafcProjectMapper;
import com.lumlord.model.controlled.ControlledProgramMaterialEntity;
import com.lumlord.model.common.UserInfo;
import com.lumlord.model.request.ProgramMaterialUnionControlledInfoRequest;
import com.lumlord.model.request.AreaIdRequest;
import com.lumlord.model.request.GetProgramMaterialby2WayRequest;
import com.lumlord.model.vo.*;
import com.lumlord.service.controlled.ControlledProgramMaterialService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 受控节目素材 服务实现类
 * </p>
 *
 * @author luosj
 * @since 2021-10-19
 */
@Service
public class ControlledProgramMaterialServiceImpl extends ServiceImpl<ControlledProgramMaterialMapper, ControlledProgramMaterialEntity> implements ControlledProgramMaterialService {

    @Autowired
    private ControlledInfoMapper controlledInfoMapper;

    @Autowired
    private OperatingUnitInfoMapper operatingUnitInfoMapper;

    @Autowired
    private ControlledProgramMaterialMapper controlledProgramMaterialMapper;

    @Autowired
    private ProjectAreaForControlledMapper projectAreaForControlledMapper;

    @Autowired
    private PafcProjectMapper pafcProjectMapper;

    @Autowired
    private BaseOperatingUnitProjectMapper baseOperatingUnitProjectMapper;

    @Override
    public GetProgramMaterialBy2WayResultVo getProgramMaterialby2Way(GetProgramMaterialby2WayRequest request, UserInfo user) {
        // inquiryMode  0:按行政区域划分
        if (request.getInquiryMode() == 0) {
            return getByAdministrativeRegion(request, user);
        }
        // inquiryMode  1：按运营单位划分
        if (request.getInquiryMode() == 1) {
            return getByOperatingUnit(request, user);
        }
        return null;
    }

    private GetProgramMaterialBy2WayResultVo getByAdministrativeRegion(GetProgramMaterialby2WayRequest request, UserInfo user) {
        List<Integer> allProjectAreaForControlledIds = projectAreaForControlledMapper.getAllProjectAreaForControlledIds(user);
        // set接收所有查询到的数据
        Set<GetProgramMaterialBy2WayVo> set = new HashSet<>();
        if (!CollectionUtils.isEmpty(allProjectAreaForControlledIds)) {
            for (Integer projectAreaForControlledId:allProjectAreaForControlledIds) {
                // 根据所属区域id，获取该区域所有的项目id
                Set<Integer> projectIds = pafcProjectMapper.getProjectIdByProjectAreaForControlledId(projectAreaForControlledId);
                if (!CollectionUtils.isEmpty(projectIds)) {
                    // 获取所有项目下的所有受控节目素材相关数据
                    for (Integer projectId:projectIds) {
                        // 根据受控系统名称和项目id 获取 受控系统信息（按行政区域划分）
                        List<GetProgramMaterialBy2WayVo> controlledProgramMaterials = controlledInfoMapper.getInfoByAdministrativeRegion(projectId, request.getControlledSystemName(), user);
                        for (GetProgramMaterialBy2WayVo controlledProgramMaterial:controlledProgramMaterials) {
                            Integer id = controlledProgramMaterial.getControlledInfoId();
                            // 根据 受控系统信息id 查询 受控节目素材
                            List<ControlledProgramMaterialEntity> controlledProgramMaterialEntities = getControlledProgramMaterialEntitiesByControlledInfoId(id);
                            // 将“受控节目素材”设置到 controlledProgramMaterial
                            controlledProgramMaterial
                                    .setControlledProgramMaterials(controlledProgramMaterialEntities);
                        }
                        set.addAll(controlledProgramMaterials);
                    }
                }
            }
        }
        // 返回最终封装的结构 Set<ProvinceUnionVo>
        return getProvinceUnionVos(set);
    }

    private GetProgramMaterialBy2WayResultVo getProvinceUnionVos(Set<GetProgramMaterialBy2WayVo> set) {
        // 初始化返回结果
        GetProgramMaterialBy2WayResultVo getProgramMaterialBy2WayResultVo = new GetProgramMaterialBy2WayResultVo();
        // 封装返回数据
        Set<ProvinceUnionVo> provinceUnionVos = new HashSet<>();
        Set<CityUnionVo> cityUnionVos = new HashSet<>();
        Set<CountyUnionVo> countyUnionVos = new HashSet<>();
        Set<StreetUnionVo> streetUnionVos = new HashSet<>();
        Set<CommunityUnionVo> communityUnionVos = new HashSet<>();
        // 获取 省/直辖市、市、区、街道、社区 的 映射对象
        Set<ProvinceVo> provinces = set.stream().map(e -> new ProvinceVo(e.getProvinceId(), e.getProvince())).collect(Collectors.toSet());
        Set<CityVo> cities = set.stream().map(e -> new CityVo(e.getCityId(), e.getCity(), e.getProvinceId())).collect(Collectors.toSet());
        Set<CountyVo> counties = set.stream().map(e -> new CountyVo(e.getCountyId(), e.getCounty(), e.getCityId())).collect(Collectors.toSet());
        Set<StreetVo> streets = set.stream().map(e -> new StreetVo(e.getStreetId(), e.getStreet(), e.getCountyId())).collect(Collectors.toSet());
        Set<CommunityVo> communities = set.stream().map(e -> new CommunityVo(e.getCommunityId(), e.getCommunity(), e.getStreetId())).collect(Collectors.toSet());
        // 社区级封装
        for (CommunityVo community:communities){
            Set<GetProgramMaterialBy2WayVo> getProgramMaterialBy2WayVos = set.stream().filter(e -> e.getCommunityId().equals(community.getCommunityId())).collect(Collectors.toSet());
            communityUnionVos.add(new CommunityUnionVo(community, getProgramMaterialBy2WayVos));
        }
        // 街道级封装
        for (StreetVo street:streets){
            Set<CommunityUnionVo> collect = communityUnionVos.stream().filter(e -> e.getCommunityVo().getStreetId() == street.getStreetId()).collect(Collectors.toSet());
            streetUnionVos.add(new StreetUnionVo(street, collect));
        }
        // 区级封装
        for (CountyVo county:counties){
            Set<StreetUnionVo> collect = streetUnionVos.stream().filter(e -> e.getStreetVo().getCountyId() == county.getCountyId()).collect(Collectors.toSet());
            countyUnionVos.add(new CountyUnionVo(county, collect));
        }
        // 市级封装
        for (CityVo city:cities){
            Set<CountyUnionVo> collect = countyUnionVos.stream().filter(e -> e.getCountyVo().getCityId() == city.getCityId()).collect(Collectors.toSet());
            cityUnionVos.add(new CityUnionVo(city, collect));
        }
        // 省/直辖市级封装
        for (ProvinceVo province:provinces){
            Set<CityUnionVo> collect = cityUnionVos.stream().filter(e -> e.getCityVo().getProvinceId() == province.getProvinceId()).collect(Collectors.toSet());
            provinceUnionVos.add(new ProvinceUnionVo(province, collect));
        }
        getProgramMaterialBy2WayResultVo.setGetByAdministrativeRegion(provinceUnionVos);
        return getProgramMaterialBy2WayResultVo;
    }

    private List<ControlledProgramMaterialEntity> getControlledProgramMaterialEntitiesByControlledInfoId(Integer id) {
        return controlledProgramMaterialMapper
                .selectList(new QueryWrapper<ControlledProgramMaterialEntity>()
                        .lambda()
                        .eq(ControlledProgramMaterialEntity::getControlledInfoId, id));
    }
}
